
package jpave.manager;
/*************************************************************
 * Store all data.
 * Reads/writes LIB.cfg and sTCW.cfg
 * Import annoDB
 * Reads HOSTS.cfg
 */
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.sql.ResultSet;
import java.util.Vector;
import javax.swing.JOptionPane;

import assem.DBConn;

import jpave.annotator.CoreMain;
import jpave.dataholders.GlobalSettings;
import util.Debug.ErrorReport;
import util.methods.BlastArgs;
import util.methods.HostsCfg;
import util.methods.PaveProps;
import util.methods.PropType;
import util.methods.Version;

public class ManagerData {
	private final static int NUMANNODBS = 20;
	private final static String LIBDIR = ManagerFrame.LIBDIR;
	private final static String PROJDIR = ManagerFrame.PROJDIR;
	private final static String STCW = GlobalSettings.STCW;
	private final static String STCWCFG = GlobalSettings.STCWCFG;
	private final static String LIBCFG = GlobalSettings.LIBCFG;
	
	public ManagerData() {
		annoData = new Vector<AnnoData> ();
		expLibData = new Vector<ExpLibData> ();
		repData = new Vector<RepData> ();
		transLibData = new Vector<TransLibData> ();
		countData = new Vector<CountData> ();
		theTCs = new Vector<String> ();
	}
	
	/***************************************************
	 * called when loading a project
	 */
	public static void validateProjectFiles(String projectName) {
		try {
			File libFile = new File(LIBDIR + projectName);
			File projFile = new File(PROJDIR + projectName);
			
			if(!libFile.exists()) {
				System.err.println("Creating: " + libFile.getAbsolutePath());
				libFile.mkdir();
			}
			if(!projFile.exists()) {
				System.err.println("Creating: " + projFile.getAbsolutePath());
				projFile.mkdir();
			}
		    String db = projectName;
	        if (!db.startsWith(STCW)) db = STCW + db;		

			projFile = new File(ManagerFrame.PROJDIR + projectName + "/PAVE.cfg");
			if(projFile.exists()) { 
                System.err.println("Rename PAVE.cfg to sTCW.cfg");
                File newFile = new File(PROJDIR + projectName + "/" + STCWCFG);
                projFile.renameTo(newFile);
            }
			String cfg = PROJDIR + projectName + "/" + STCWCFG;
			projFile = new File(cfg);
			if(!projFile.exists()) {
				System.err.println("Creating " + cfg);
				projFile = new File(cfg);
				BufferedWriter out = new BufferedWriter(new FileWriter(projFile));
				
				out.write("# " + projectName + " " + STCWCFG + " " + Version.strPAVEver + "\n");
				out.write("AssemblyID    = " + projectName + " # singleTCW ID\n");
				out.write("PAVE_db       = " + db + "   # sTCW Database\n");
				
				out.close();
			}
			cfg = LIBDIR + projectName + "/" + LIBCFG;
			libFile = new File(cfg);
			if(!libFile.exists()) {
				System.out.println("Creating " + cfg);
				BufferedWriter out = new BufferedWriter(new FileWriter(libFile));
				
				out = new BufferedWriter(new FileWriter(libFile));
				out.write("# " + projectName +  " " + LIBCFG + " "  + Version.strPAVEver + "\n");
				out.write("PAVE_db       = " + db + "   # sTCW database\n");
				out.close();
			}
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error creating default values");
		}
	}
	
	public static ManagerData createNewProject(String projectName) {
		ManagerData retVal = new ManagerData();
		retVal.strProject = projectName;
		
		File libFile = new File(LIBDIR + projectName);
		File projFile = new File(PROJDIR + projectName);

		if(!libFile.exists()) {
			System.err.println("Creating: " + libFile.getAbsolutePath());
			libFile.mkdir();
		}
		if(!projFile.exists()) {
			System.err.println("Creating: " + projFile.getAbsolutePath());
			projFile.mkdir();
		}
		
		retVal.setAssemblyID(projectName);
		retVal.setPAVEDB(STCW + projectName);
		retVal.setSkipAssembly(true);
		saveLIBcfg_sTCWcfg(retVal);
		
		return retVal;
	}
	/**************************************************************
	 * Called from ManagerFrame before a save
	 */
	public static String hasDuplicates(ManagerData theData) {
		//Trans libs
		for(int x=0; x<theData.getNumTransLibs(); x++) {
			String transLibID = theData.getTransLibraryAt(x).getTransLibID();
			String transPrefix = theData.getTransLibraryAt(x).getExpPrefix();
			for(int y=x+1; y<theData.getNumTransLibs(); y++) {
				if(transLibID.equals(theData.getTransLibraryAt(y).getTransLibID()) &&
						transPrefix.equals(theData.getTransLibraryAt(y).getExpPrefix()))
					return "Duplicate Trans/Read ID: " + transLibID;
			}
			
			// CAS 1/14/15 also check against expression
			for(int y=x+1; y<theData.getNumExpLibs(); y++) {
				if(transLibID.equals(theData.getExpLibraryAt(y).getLibID()) &&
						transPrefix.equals(theData.getExpLibraryAt(y).getPrefix()))
					return "Trans ID same as Lib name in count file: " +  transLibID;
			}
		}

		//Exp libs
		for(int x=0; x<theData.getNumExpLibs(); x++) {
			String expLibID = theData.getExpLibraryAt(x).getLibID();
			String expPrefix = theData.getExpLibraryAt(x).getPrefix();
			
			for(int y=x+1; y<theData.getNumExpLibs(); y++) {
				if(expLibID.equals(theData.getExpLibraryAt(y).getLibID()) &&
						expPrefix.equals(theData.getExpLibraryAt(y).getPrefix()))
					return "Duplicate Lib names in count file: " + expLibID;
			}
		}
		return null;
	}
	
	public static boolean hasValidID(ManagerData theData) {
		return theData.getAssemblyID().matches("[A-Za-z_0-9]+");
	}
	
	/*************************************************************
	 * XXX save LIB.cfg and sTCW.cfg
	 */
	public static boolean saveLIBcfg_sTCWcfg(ManagerData theData) {
		try {
			String libDir = LIBDIR + theData.strProject;
			File libFile = new File(libDir + "/" + LIBCFG);
			File projFile = new File(PROJDIR + theData.strProject + "/" + STCWCFG);
			
			BufferedWriter out = new BufferedWriter(new FileWriter(projFile));
			PaveProps theProps = new PaveProps(PropType.Assem);
			
			/*
			 *  write projects/<project>/sTCW.cfg
			 */
			out.write("# " + theData.strProject + " sTCW.cfg " + Version.strPAVEver + "\n");
			out.write("AssemblyID = " + theData.getAssemblyID() + "  # singleTCW ID\n");
			out.write("# Database parameters (same as in LIB.cfg)\n");
			out.write("PAVE_db       = " + theData.getPAVEDB() + "  # Database \n");
			out.write("\n");
			if(theData.getClique().length() > 0 && !theData.getClique().equals(theProps.getProperty("CLIQUE")))
				out.write("CLIQUE     = " + theData.getClique() +"\n");
			if(theData.getCliqueBlastEval().length() > 0 && !theData.getCliqueBlastEval().equals(theProps.getProperty("CLIQUE_BLAST_EVAL")))
				out.write("CLIQUE_BLAST_EVAL  = " + theData.getCliqueBlastEval() +"\n");
			if(theData.getCliqueBlastParam().length() > 0 && !theData.getCliqueBlastParam().equals(theProps.getProperty("CLIQUE_BLAST_PARAMS")))
				out.write("CLIQUE_BLAST_PARAMS   = " + theData.getCliqueBlastParam() +"\n");
			if(theData.getSelfJoin().length() > 0 && !theData.getSelfJoin().equals(theProps.getProperty("SELF_JOIN")))
				out.write("SELF_JOIN = " + theData.getSelfJoin() +"\n");
			if(theData.strBuryBlastEval.length() > 0 && !theData.strBuryBlastEval.equals(theProps.getProperty("BURY_BLAST_EVAL")))
				out.write("BURY_BLAST_EVAL = " + theData.strBuryBlastEval +"\n");
			if(theData.strBuryBlastIdentity.length() > 0 && !theData.strBuryBlastIdentity.equals(theProps.getProperty("BURY_BLAST_IDENTITY")))
				out.write("BURY_BLAST_IDENTITY = " + theData.strBuryBlastIdentity +"\n");
			if(theData.strBuryBlastParams.length() > 0 && !theData.strBuryBlastParams.equals(theProps.getProperty("BURY_BLAST_PARAMS")))
				out.write("BURY_BLAST_PARAMS = " + theData.strBuryBlastParams +"\n");
			if(theData.strCAPArgs.length() > 0 && !theData.strCAPArgs.equals(theProps.getProperty("CAP_ARGS")))
				out.write("CAP_ARGS = " + theData.strCAPArgs +"\n");
			if(theData.strTCBlastEval.length() > 0 && !theData.strTCBlastEval.equals(theProps.getProperty("TC_BLAST_EVAL")))
				out.write("TC_BLAST_EVAL = " + theData.strTCBlastEval +"\n");
			if(theData.strTCBlastParams.length() > 0 && !theData.strTCBlastParams.equals(theProps.getProperty("TC_BLAST_PARAMS")))
				out.write("TC_BLAST_PARAMS = " + theData.strTCBlastParams +"\n");
			if(theData.strUserESTSelfBlast.length() > 0)
				out.write("User_EST_selfblast = " + theData.strUserESTSelfBlast +"\n");
			out.write("\n");
			
			int numTCs = -1;
			//Check # of TCs
			for(int x=1; numTCs < 0; x++)
				if(!theProps.containsKey("TC" + x))
					numTCs = x-1;
			
			boolean writeTCs = (numTCs != theData.theTCs.size());
			
			//if same # of TCs, get for any different values
			for(int x=0; x<theData.theTCs.size() && !writeTCs; x++) {
				try {
					String val = theProps.getProperty("TC" + (x+1));
					if(val != null && !theData.theTCs.get(x).equals(val))
						writeTCs = true;
				}
				catch(Exception e) {
					writeTCs = true;
				}
			}

			if(writeTCs) {
				for(int x=0; x<theData.theTCs.size(); x++) {
					out.write("TC" + (x+1) + " = " + theData.theTCs.get(x) +"\n");
				}
			}
			out.write("\n");
			if (!theData.bSkipAssembly) out.write("SKIP_ASSEMBLY = 0\n"); // Note, now defaulting to 1
			if(/*theProps.getProperty("USE_TRANS_NAME").equals("1") != */theData.bUseTransNames)
				out.write("USE_TRANS_NAME = " + (theData.bUseTransNames?"1":"0") +"\n");
			out.write("CPUs = " + theData.getNumCPUs() + "\n\n");
			out.flush();

			if(theData.getUnitransTSelfBlast() != null) {
				out.write("JPAVE_unitrans_tselfblast = " + theData.getUnitransTSelfBlast() + "\n");
			}
			if(theData.getUnitransTSelfBlastParams() != null && 
					theData.getUnitransTSelfBlastParams().length() > 0 && 
					!theData.getUnitransTSelfBlastParams().equals(BlastArgs.getTblastxOptions()))
				out.write("JPAVE_tselfblast_args = " + theData.getUnitransTSelfBlastParams() + "\n");

			if(theData.getUnitransSelfBlast() != null) {
				out.write("JPAVE_unitrans_selfblast = " + theData.getUnitransSelfBlast() + "\n");
			}
			if(theData.getUnitransSelfBlastParams() != null && 
					theData.getUnitransSelfBlastParams().length() > 0
					&& !theData.getUnitransSelfBlastParams().equals(BlastArgs.getBlastnOptions()))
				out.write("JPAVE_selfblast_args = " + theData.getUnitransSelfBlastParams() + "\n");
			if(theData.getPairsLimit() > 0 && 
					theData.getPairsLimit() != CoreMain.defaultPairsLimit)
				out.write("JPAVE_pairs_limit = " + theData.getPairsLimit() + "\n");
			out.write("\n");
			out.flush();
			if(theData.getGODB().length() > 0)
				out.write("JPAVE_GO_DB = " + theData.getGODB() + "\n");

			if(theData.getUnitransType() > 0)
				out.write("JPAVE_unitrans_type = " + theData.getUnitransType() + "\n");
				
			out.write("\n");
				
			for(int x=0; x<theData.getNumAnnoDBs(); x++) {
				if(theData.getAnnoDBAt(x) == null) continue;
				AnnoData annoDB = theData.getAnnoDBAt(x);
				String comment = "";
				if(!annoDB.isSelected()) comment = "#";
					
				if(annoDB.getTaxo().length() > 0)
					out.write(comment + "JPAVE_DBtaxo_" + (x+1) + " = " + annoDB.getTaxo() + "\n");
				if(annoDB.getTabularFile().length() > 0)
					out.write(comment + "JPAVE_unitrans_DBblast_" + (x+1) + " = " + annoDB.getTabularFile() + "\n");
				if(annoDB.getFastaDB().length() > 0)
					out.write(comment + "JPAVE_DBfasta_" + (x+1) + " = " + annoDB.getFastaDB() + "\n");
				if(annoDB.getSearchPgm().length() > 0)
					out.write(comment + "JPAVE_DBsearch_pgm_" + (x+1) + " = " + annoDB.getSearchPgm() + "\n");
				if(annoDB.getParams().length() > 0)
					out.write(comment + "JPAVE_DBargs_" + (x+1) + " = " + annoDB.getParams() + "\n");
				if(annoDB.getUnannotated())
					out.write(comment + "JPAVE_unitrans_subset_" + (x+1) + " = yes\n");
				if(annoDB.getDate().length() > 0)
					out.write(comment + "JPAVE_DBdate_" + (x+1) + " = " + annoDB.getDate() + "\n");
				out.write("\n");
				out.flush();
			}
			out.close();
			
			/*
			 *  write libraries/<project>/LIB.cfg
			 */
			out = new BufferedWriter(new FileWriter(libFile));
			out.write("PAVE_db       = " + theData.getPAVEDB() + "\n");
			out.write("\n# Expression (count, spectra) libraries corresponding to translib\n");
			out.write("# Each libid should occur in a 'expfile' defined by a translib entry below\n\n");
			for(int x=0; x<theData.getNumExpLibs(); x++) {
				ExpLibData exp = theData.getExpLibraryAt(x);
				if(exp.getLibID().length() == 0) continue;
				
				String libid = exp.getLibID();
				out.write("libid     = " + libid + "\n");
				String prefix = exp.getPrefix();
				if(exp.getPrefix().length() > 0) out.write("prefix    = " + prefix + "\n");
				
				String theReps = "";
				for(int rIdx=0; rIdx < theData.getNumReps(); rIdx++) {
					RepData rep = theData.getRepLibraryAt(rIdx);
					if (libid.equals(rep.getLibID()) && prefix.equals(rep.strPrefix)) {
						if(theReps.length() == 0) theReps = rep.strRepID;
						else theReps += ", " + rep.strRepID;
					}
				}
				if(theReps.length() > 0) out.write("reps       = " + theReps + "\n");
				
				saveMetaData(exp, out);
			}
			out.write("# Libraries with sequences to be assembled.\n\n");
			for(int x=0; x<theData.getNumTransLibs(); x++) {
				TransLibData trans = theData.getTransLibraryAt(x);
				if(trans.getExpFile().length() != 0) continue;
				
				out.write("libid         = " + trans.getTransLibID() + "\n");
				if(trans.getSeqFile().length() > 0) out.write("seqfile       = " + trans.getSeqFile() + "\n");
				if(trans.getQualFile().length() > 0)out.write("qualfile      = " + trans.getQualFile() + "\n");
				if(trans.getFivePrimeSuffix().length() > 0) out.write("fiveprimesuf  = " + trans.getFivePrimeSuffix() + "\n");
				if(trans.getThreePrimeSuffix().length() > 0)out.write("threeprimesuf = " + trans.getThreePrimeSuffix() + "\n");
				
				saveMetaData(trans, out);
			}
			out.write("# Sequence (Transcript or protein) library, with optional expression (count, spectra) data.\n\n");
			for(int x=0; x<theData.getNumTransLibs(); x++) {
				TransLibData trans = theData.getTransLibraryAt(x);
				if(trans.getExpFile().length() == 0) continue;
				
				out.write("translib     = " + trans.getTransLibID() + "\n");
				if(trans.getExpPrefix().length() > 0) out.write("prefix       = " + trans.getExpPrefix() + "\n");
				if(trans.getSeqFile().length() > 0) out.write("seqfile      = " + trans.getSeqFile() + "\n");
				if(trans.getQualFile().length() > 0)out.write("qualfile     = " + trans.getQualFile() + "\n");
				out.write("expfile      = " + trans.getExpFile() + "\n");
				
				saveMetaData(trans, out);
			}
			
			out.write("# Files used for generating library count file\n\n");
			for(int x=0; x<theData.getNumCountFiles(); x++) {
				out.write("count_file" + (x+1) + "\t= " + theData.getCountFileAt(x) + "\n");
				out.write("count_name" + (x+1) + "\t= " + theData.getCountHeaderAt(x) + "\n\n");
			}
			out.close();
			return true;
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error writing config files");
			return false;
		}
	}
	private static void saveMetaData(TransLibData trans, BufferedWriter out) {
		try {
			if(trans.getTitle().length() > 0)	out.write("title     = " + trans.getTitle() + "\n");
			if(trans.getCultivar().length() > 0)	out.write("cultivar  = " + trans.getCultivar() + "\n");
			if(trans.getTissue().length() > 0)	out.write("tissue    = " + trans.getTissue() + "\n");
			if(trans.getStage().length() > 0)	out.write("stage     = " + trans.getStage() + "\n");
			if(trans.getTreatment().length() > 0)out.write("treatment = " + trans.getTreatment() + "\n");
			if(trans.getOrganism().length() > 0)	out.write("organism  = " + trans.getOrganism() + "\n");
			if(trans.getStrain().length() > 0)	out.write("strain    = " + trans.getStrain() + "\n");
			if(trans.getYear().length() > 0)		out.write("year      = " + trans.getYear() + "\n");
			if(trans.getSource().length() > 0)	out.write("source    = " + trans.getSource() + "\n");
			out.write("\n");
			out.flush();
		}
		catch(Exception e) {ErrorReport.prtReport(e, "Error writing config file metadata");}
	}
	private static void saveMetaData(ExpLibData exp, BufferedWriter out) {
		try {
			if(exp.getTitle().length() > 0)		out.write("title     = " + exp.getTitle() + "\n");
			if(exp.getCultivar().length() > 0)	out.write("cultivar  = " + exp.getCultivar() + "\n");
			if(exp.getTissue().length() > 0)		out.write("tissue    = " + exp.getTissue() + "\n");
			if(exp.getStage().length() > 0)		out.write("stage     = " + exp.getStage() + "\n");
			if(exp.getTreatment().length() > 0)	out.write("treatment = " + exp.getTreatment() + "\n");
			if(exp.getOrganism().length() > 0)	out.write("organism  = " + exp.getOrganism() + "\n");
			if(exp.getStrain().length() > 0)		out.write("strain    = " + exp.getStrain() + "\n");
			if(exp.getYear().length() > 0)		out.write("year      = " + exp.getYear() + "\n");
			if(exp.getSource().length() > 0)		out.write("source    = " + exp.getSource() + "\n");
			out.write("\n");
			out.flush();
		}
		catch(Exception e) {ErrorReport.prtReport(e, "Error writing config file metadata");}
	}
	
	/**************************************************************
	 * called by ManagerFrame to read sTCW.cfg for a project to display all overview
	 */
	public static ManagerData readsTCWcfg(String project) {
		try {
			ManagerData manData = new ManagerData();
			manData.strProject = project;
			String line = "", key = "", value = "";
			//Validate config files
			File projFile = new File("projects/" + manData.strProject + "/PAVE.cfg");
			if(!projFile.exists()) {
			    new File("projects/" + manData.strProject + "/sTCW.cfg"); 
			    if (!projFile.exists()) {
			        System.err.println("Error: Project sTCW.cfg file does not exist");
			        return null;
			    }   
			}

			BufferedReader projReader = new BufferedReader(new FileReader(projFile));
			AnnoData [] tempAnnos = new AnnoData[NUMANNODBS];
			for(int x=0; x<tempAnnos.length; x++)
				tempAnnos[x] = null;
			
			while((line = projReader.readLine()) != null) {
				line = removeComment(line);
				if(line.indexOf('=') > 0) {
					String [] lineVal = line.split("=");
					
					if(lineVal.length > 1) {
						key = lineVal[0].trim();
						value = lineVal[1].trim();
						manData.setValueProj(key, value, tempAnnos);
					}
				}					
			}
			for(int x=0; x<tempAnnos.length; x++) {
				if(tempAnnos[x] != null)
					manData.annoData.add(tempAnnos[x]);
			}
			projReader.close();
			
			return manData;
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Loading project data failed");
		}
		return null;
	}
	/***********************************************************
	 * Reads the LIB.cfg and sTCW.cfg when a project is loaded
	 */
	public static ManagerData readLIBcfg_sTCWcfg(HostsCfg hostsObj, String project) {
		try {
			ManagerData manData = new ManagerData();
			manData.strProject = project;
			String line = "", key = "", value = "";
			
			File libFile = new File(LIBDIR + manData.strProject + "/" + LIBCFG);
			if (!libFile.exists()) {
			    System.err.println("File does not exist: " + "libraries/" + manData.strProject + "/LIB.cfg");
			    return manData;
			}
			File projFile = new File(PROJDIR + manData.strProject + "/" + STCWCFG);
			if(!projFile.exists()) {
			    System.err.println("File does not exist: " + "projects/" + manData.strProject + "/sTCW.cfg");
	            return manData;
			}			
			
			/*
			 *  read sTCW.cfg
			 */
			BufferedReader projReader = new BufferedReader(new FileReader(projFile));
			AnnoData [] tempAnnos = new AnnoData[NUMANNODBS];
			for(int x=0; x<tempAnnos.length; x++)
				tempAnnos[x] = null;
			
			while((line = projReader.readLine()) != null) {
				line = removeComment(line);
				if(line.indexOf('=') > 0) {
					String [] lineVal = line.split("=");
					
					if(lineVal.length > 1) {
						key = lineVal[0].trim();
						value = lineVal[1].trim();
						manData.setValueProj(key, value, tempAnnos);
					}
				}					
			}
			for(int x=0; x<tempAnnos.length; x++) {
				if(tempAnnos[x] != null)
					manData.annoData.add(tempAnnos[x]);
			}
			projReader.close();		
			/* 
			 * read LIB.cfg
			 */
			BufferedReader libReader = new BufferedReader(new FileReader(libFile));
			boolean transLib = false; // once a translib keyword is found, goes into different mode		
			
			while((line = libReader.readLine()) != null) {
				line = removeComment(line);
				if(line.indexOf('=') == 0) continue;	
				String [] lineVal = line.split("=");
				if(lineVal.length <= 1) continue;
				
				key = lineVal[0].trim();
				value = lineVal[1].trim();

				if(key.equalsIgnoreCase("libid")) transLib = false;
				else if(key.equalsIgnoreCase("translib")) transLib = true;
				
				// we can't remove any of these if options or the loop will
				// drop down and parse them as libid headers!!
				if(key.equalsIgnoreCase("PAVE_db")) {}
				else if(key.equalsIgnoreCase("PAVE_host") || key.equalsIgnoreCase("DB_host") ) {}
				else if(key.equalsIgnoreCase("PAVE_user") || key.equalsIgnoreCase("DB_user")) {}
				else if(key.equalsIgnoreCase("PAVE_password") || key.equalsIgnoreCase("DB_password") ) {}
				else if(key.startsWith("count_file")) {
					int pos = Integer.parseInt(key.substring("count_file".length())) - 1;
					while(pos >= manData.getNumCountFiles()) {
						manData.addNewCountFile("", "");
					}
					manData.setCountFileAt(pos, value);
				}
				else if(key.startsWith("count_name")) {
					int pos = Integer.parseInt(key.substring("count_file".length())) - 1;
					while(pos >= manData.getNumCountFiles()) {
						manData.addNewCountFile("", "");
					}
					manData.setCountLabelAt(pos, value);							
				}
				// XXX - a translib object is made for either libid or translib
				// if the key is 'libid' or 'translib', all subsequent keywords are added to it.
				// if a libid is found in the header of an expression file, an expression object is created
				// 	and its translib object deleted.
				else if (!transLib) {
					if(key.equals("reps")) 
						manData.setValueReps(value);
					else 
						manData.setValueTransLib(key, value);
				}
				else if(transLib) {
					manData.setValueTransLib(key, value);
					String transID = manData.getCurrentTransID();
					String prefix = manData.getCurrentTransPrefix();
					
					if(key.equals("expfile")) {
						File temp = null;				
						if(value.startsWith("/")) temp = new File(value);
						else temp = new File("libraries/" + manData.strProject + "/" + value);
						
						if(!temp.exists()) {
							System.out.println("Warning: Missing count file: " + temp.getAbsolutePath());
							readDB(hostsObj, manData, transID, prefix);
						}
						else {
							String [] expLibs = readExpLevelLibs(project, temp);
							if(expLibs != null) {
								for(int x=0; x<expLibs.length; x++) {				
									manData.assignTransToExp(transID, expLibs[x], prefix);
								}						
							}
							else JOptionPane.showMessageDialog(null, "No counts in file: \n" + 
									temp.getAbsolutePath(), "Warn", JOptionPane.PLAIN_MESSAGE);
						}
					}
				}		
			} // end while loop through file
			
			libReader.close();
			cleanLoadData(manData);

			return manData;
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Loading LIB.cfg and sTCW.cfg  failed");
		}
		return null;
	}
	/***********************************************************
	 * 12/14/14 file not there, so read rep labels from database
	 */
	private static void readDB(HostsCfg hostsObj, ManagerData man, String transID, String prefix) {
		String db = man.getPAVEDB();
		try {
           DBConn conn = hostsObj.getDBConn(db);
           if (conn==null) return;
        	   		
		   ResultSet rs = conn.executeQuery("SELECT reps FROM library where parent='" + transID + "'");
		   while (rs.next()) {
			   String reps = rs.getString(1); 
			   String [] repList = reps.split(",");
			   for(int x=0; x<repList.length; x++) {				
					man.assignTransToExp(transID, repList[x].trim(), prefix);
				}
		   } 
		   System.out.println("Since count file is missing, read reps from database " + db);
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error reading reps from database " + db);
		}
	}
	/****************************************************************
	 * Reads an expression file for first line which contains library names
	 */
	public static String [] readExpLevelLibs(String project, File sourceFile) {
		try {
			System.err.println("Reading " + sourceFile + " for count library names");
			BufferedReader projReader = new BufferedReader(new FileReader(sourceFile));
			String line = "";
			String [] retVal = null;
			if((line = projReader.readLine()) != null) {
				String [] vals = line.split("\\s+");
				if(vals.length > 1) {
					retVal = new String[vals.length - 1];
					for(int x=1; x<vals.length; x++) {
						retVal[x-1] = vals[x].trim();
					}
				}
				else {
					JOptionPane.showMessageDialog(null, "Error parsing header for count file", "Error", JOptionPane.PLAIN_MESSAGE);
					System.out.println("Error parsing header for count file: " + line);
					return new String[0];
				}
			}
			projReader.close();
			
			String x = "";
			for (int i=0; i<retVal.length; i++) x += retVal[i] + " ";
			System.out.println("Count libraries: " + x);
			
			// CAS 1/14/15 added check for duplicate lib names
			for (int i=0; i<retVal.length-1; i++)
				for (int j=i+1; j<retVal.length; j++) {
					if (retVal[i].equals(retVal[j])) {
						JOptionPane.showMessageDialog(null, "Duplicate read count library name: " + retVal[i] +
								"\nFix library name, remove transcript library and then re-add", 
								"Error", JOptionPane.PLAIN_MESSAGE);
						System.out.println("Error: duplicate read count library name " + retVal[i]);
						System.out.println("Remove transcript library and re-add after fixing library name");
						return new String[0];
					}
				}
			return retVal;
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Loading expression level data failed");
		}
		return null;
	}
		
	/**************************************************
	 * called while reading the LIB.cfg for a project
	 * when a libid is found, it is not known if its read file (no expression)
	 * or an expression file, so everything is made a Translib and changed to
	 * expData if found in expression file.
	 */
	public boolean setValueTransLib(String key, String value) {
		int index = transLibData.size()-1;

		if(key.equalsIgnoreCase("libid") || key.equalsIgnoreCase("translib")) {
			transLibData.add(new TransLibData());
			transLibData.get(index+1).strTransLibID = value;
		}
		else if(key.equalsIgnoreCase("seqfile")) transLibData.get(index).strSeqFile = value;
		else if(key.equalsIgnoreCase("qualfile")) transLibData.get(index).strQualFile = value;
		else if(key.equalsIgnoreCase("fiveprimesuf")) transLibData.get(index).strFivePrimeSuf = value;
		else if(key.equalsIgnoreCase("threeprimesuf")) transLibData.get(index).strThreePrimeSuf = value;
		else if(key.equalsIgnoreCase("expfile")) transLibData.get(index).strExpFile = value;
		else if(key.equalsIgnoreCase("prefix")) transLibData.get(index).strExpPrefix = value;
		else 
			return transLibData.get(index).setAttribute(key, value);
		return true;
	}
	private void setValueReps(String value) {
		int index = transLibData.size()-1; // libid has been added
		String libid = transLibData.get(index).getTransLibID();
		String prefix = transLibData.get(index).strExpPrefix;
		String [] repIDs = value.split(",");
		for(int x=0; x<repIDs.length; x++) {
			RepData temp = new RepData();
			temp.setRepID(repIDs[x].trim());
			temp.setLibID(libid);
			temp.setExpPrefix(prefix);
			repData.add(temp);
		}
	}
	/*****************************************************
	 * Adding Reps from expression file, they have already been defined
	 * Link them to the transID
	 */
	private void assignTransToExp(String transID, String filelibid, String prefix) {
		// is not a replica
		for(int x=0; x<transLibData.size(); x++) {
			TransLibData trans = transLibData.get(x);
			if (trans.getTransLibID().equalsIgnoreCase(filelibid) 
					&& trans.getExpPrefix().equalsIgnoreCase(prefix)) {
				ExpLibData lib = new ExpLibData(transID, transLibData.get(x));
				expLibData.add(lib);
				transLibData.remove(x);
				return;
			}
		}
		// is a replica		
		for (int r=0; r < repData.size(); r++) {
			RepData rep = repData.get(r);
			if (rep.getRepID().equalsIgnoreCase(filelibid)) { // find the rep
				rep.setTransID(transID);
				String libid = rep.getLibID();
				
				for (int x=0; x<expLibData.size(); x++) { // already moved to expLibData?
					ExpLibData exp = expLibData.get(x);
					if (exp.getLibID().equalsIgnoreCase(libid)) {
						exp.addNumReps();
						return;
					}
				}
				
				for(int x=0; x<transLibData.size(); x++) { // finds its transLib 
					TransLibData trans = transLibData.get(x);
					if(trans.getTransLibID().equalsIgnoreCase(libid)) { // change to expLib
						ExpLibData lib = new ExpLibData(transID, transLibData.get(x));
						expLibData.add(lib);
						transLibData.remove(x);
						return;
					}
				}
			}
		}
		System.err.println("Error: for TransLib=" + transID + " -- its expression file has lib name=" + filelibid);
		System.err.println("       This library name is not found in LIB.cfg");
	}
	/**********************************************************
	 * XXX Called from ManagerFrame.updateTransLibUI on Add
	 * 		if added, need to be added to expression
	 */
	public boolean addLibToExp(String transID, String libid, String prefix) {
		ExpLibData newExp = new ExpLibData();
		newExp.setLibID(libid);
		newExp.setTransID(transID);
		newExp.setPrefix(prefix);
		
		if(!expLibData.contains(newExp)) {
			boolean valid = true;
			for(int x=0; x<expLibData.size(); x++) {
				if(expLibData.get(x).strLibID.equals(libid) 
						&& expLibData.get(x).strPrefix.equals(prefix))
					valid = false;
			}
			
			if(valid)
				expLibData.add(newExp);
			else System.err.println("Duplicate library ID: " + libid + " in " + transID);
			
			return valid;
		} 
		return false;
	}
	
	/************************************************************
	 * Assigns translib ID to each exp level library
	 * and sets some defaults for annoDB
	 */
	private static void cleanLoadData(ManagerData manData) {
		//Set common annoDB default
		Vector<String> uniqueArgs = new Vector<String> ();
		Vector<Integer> argCounts = new Vector<Integer> ();
		for(int x=0; x<manData.getNumAnnoDBs(); x++) {
			if(!uniqueArgs.contains(manData.getAnnoDBAt(x).getParams()) && 
					(manData.getAnnoDBAt(x).getParams().length() > 0)) {
				uniqueArgs.add(manData.getAnnoDBAt(x).getParams());
				argCounts.add(new Integer(1));
			}
			else if(manData.getAnnoDBAt(x).getParams().length() > 0){
				int pos = uniqueArgs.indexOf(manData.getAnnoDBAt(x).getParams());
				argCounts.set(pos, argCounts.get(pos)+1);
			}
		}
		int maxCountIdx = 0;
		for(int x=1; x<argCounts.size(); x++)
			if(argCounts.get(x) > argCounts.get(maxCountIdx))
				maxCountIdx = x;
		
		if(maxCountIdx < uniqueArgs.size())
			manData.strDefaultAnnoBlastParams = uniqueArgs.get(maxCountIdx);
		else {
			manData.setDefaultAnnoDBBlastParams(BlastArgs.getBlastxOptions());
		}
	}
	
	public boolean setValueExpLib(String key, String value) {
		int index = expLibData.size()-1;
		if(key.equalsIgnoreCase("libid")) {
			expLibData.add(new ExpLibData());
			expLibData.get(index+1).strLibID = value;
		}
		else if(key.equalsIgnoreCase("prefix")) {
			expLibData.get(index).strPrefix = value;
		}
		else if(expLibData.size() > 0)
			return expLibData.get(index).setAttribute(key, value);
		return true;
	}
	
	public void removeExpLib(String transID, String libName) {
		for(int x=0; x<expLibData.size(); x++) {
			if(expLibData.get(x).strLibID.equalsIgnoreCase(libName) && 
					expLibData.get(x).strTransID.equalsIgnoreCase(transID)) {
				expLibData.removeElementAt(x);
				return;
			}
		}
	}
	private static String removeComment(String line) {
		if(line.indexOf('#') >= 0) {
			//Allow disabled annoDBs to be read
			if(line.indexOf("#JPAVE_DBtaxo_") >= 0 || line.indexOf("#JPAVE_unitrans_DBblast_") >= 0 || 
			   line.indexOf("#JPAVE_DBfasta_") >= 0 || line.indexOf("#JPAVE_DBargs_") >= 0 || 
			   line.indexOf("#JPAVE_unitrans_subset_") >= 0 || line.indexOf("#JPAVE_DBdate_") >= 0 ||
			   line.indexOf("#JPAVE_DBsearch_pgm_") >= 0)
				return line;
			return line.substring(0, line.indexOf('#'));
		}
		return line;
	}
	
	public int getNumExpLibs() { return expLibData.size(); }
	public int getNumReps() { return repData.size(); }
	public int getNumTransLibs() { return transLibData.size(); }	
	public int getNumAnnoDBs() { return annoData.size(); }
	
	public static void importAnnoDBs(File source, ManagerData target) {
		try {
		    System.err.println("Loading " + source.getPath());
			String line = "", key, value;
			BufferedReader projReader = new BufferedReader(new FileReader(source));
			AnnoData [] tempAnnos = new AnnoData[NUMANNODBS];
			ManagerData temp = new ManagerData();
			
			for(int x=0; x<tempAnnos.length; x++)
				tempAnnos[x] = null;
			
			while((line = projReader.readLine()) != null) {
				line = removeComment(line);
				if(line.indexOf('=') == 0) continue;
				
				String [] lineVal = line.split("=");
				if(lineVal.length > 1) {
					key = lineVal[0].trim();
					value = lineVal[1].trim();
					if(key.startsWith("JPAVE_DBtaxo_") || key.startsWith("JPAVE_DBfasta_") || 
					   key.startsWith("JPAVE_unitrans_DBblast_") ||
					   key.startsWith("JPAVE_DBargs_") || key.startsWith("JPAVE_unitrans_subset_") || 
					   key.startsWith("JPAVE_DBdate_") || key.startsWith("JPAVE_DBsearch_pgm_"))	
						temp.setValueProj(key, value, tempAnnos);
				}
						
			}
			projReader.close();
			
			for(int x=0; x<tempAnnos.length; x++) {
				if(tempAnnos[x] != null) {
					boolean found = false;
					for(int y=0; y<target.getNumAnnoDBs() && !found; y++) {
						if (target.getAnnoDBAt(y)!=null) // CAS 5/18/15 getting empty here somehow
							found = target.getAnnoDBAt(y).getFastaDB().equals(tempAnnos[x].getFastaDB());
					}
					
					if(!found) {
						int index = target.addNewAnnoDB();
						
						target.getAnnoDBAt(index).setDate(tempAnnos[x].getDate());
						target.getAnnoDBAt(index).setParams(tempAnnos[x].getParams());
						target.getAnnoDBAt(index).setFastaDB(tempAnnos[x].getFastaDB());
						target.getAnnoDBAt(index).setTaxo(tempAnnos[x].getTaxo());
						target.getAnnoDBAt(index).setTabularFile(tempAnnos[x].getTabularFile());
						target.getAnnoDBAt(index).setUnannotated(tempAnnos[x].getUnannotated());
						target.getAnnoDBAt(index).setSearchPgm(tempAnnos[x].getSearchPgm());
						target.getAnnoDBAt(index).setLoaded(false);
						target.getAnnoDBAt(index).setSelected(true);
					}
				}
			}
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error importing annoDBs");
		}
	}
	
	/**
	 * @return index of new element, -1 if full
	 */
	public int addNewExpLib() {
		expLibData.add(new ExpLibData());
		return expLibData.size() - 1;
	}
	public int addNewTransLib() {
		transLibData.add(new TransLibData());
		return transLibData.size() -1;
	}
	public int addNewAnnoDB() {
		annoData.add(new AnnoData());
		return annoData.size() - 1;
	}
	public int addNewRep() {
		repData.add(new RepData());
		return repData.size() - 1;
	}
	public void removeAllReps() {
		repData.clear();
	}

	public void removeExpLib(int index) {
		expLibData.remove(index);
	}

	// todo this does not remove from Add Lib panel
	public void removeTransLib(int index) {
		TransLibData temp = transLibData.get(index);

		for(int x=expLibData.size()-1; x>=0; x--) {
			if(expLibData.get(x).strTransID.equals(temp.strTransLibID)) {
				expLibData.remove(x);
			}
		}
		for(int x=repData.size()-1; x>=0; x--) {
			if(repData.get(x).getTransID().equals(temp.strTransLibID)) {
				repData.remove(x);
			}
		}
		transLibData.removeElementAt(index);
	}
	
	public void removeAnnoDB(int index) {
		annoData.remove(index);
	}
	
	public void moveAnnoDB(int from, int to) {
		if(from < 0 || to < 0 || from >= annoData.size() || to >= annoData.size()) return;
		
		AnnoData temp = annoData.get(from);
		annoData.set(from, annoData.get(to));
		annoData.set(to, temp);
	}
	
	public String getCurrentTransID() { return transLibData.get(transLibData.size() - 1).strTransLibID; }
	public String getCurrentTransPrefix() { return transLibData.get(transLibData.size() - 1).strExpPrefix; }
	
	public boolean setValueProj(String key, String value, AnnoData [] annoData) {
		if(key.equalsIgnoreCase("AssemblyID"))	strAssemblyID = value;
		else if(key.equalsIgnoreCase("ID"))	strAssemblyID = value;
		else if(key.equalsIgnoreCase("PAVE_db"))	strPAVEdb = value;
		else if(key.equalsIgnoreCase("CPUs"))	nCPUs = Integer.parseInt(value);
		else if(key.equalsIgnoreCase("CLIQUE"))	strClique = value;
		else if(key.equalsIgnoreCase("CLIQUE_BLAST_EVAL"))	strCliqueBlastEval = value;
		else if(key.equalsIgnoreCase("CLIQUE_BLAST_PARAMS"))	strCliqueBlastParam = value;
		else if(key.equalsIgnoreCase("SELF_JOIN"))	strSelfJoin = value;
		else if(key.equalsIgnoreCase("SKIP_ASSEMBLY")) {
			if(value.equals("1"))	bSkipAssembly = true;
			else	bSkipAssembly = false;
		}
		else if(key.equalsIgnoreCase("USE_TRANS_NAME")) bUseTransNames = value.equals("1");
		else if(key.equalsIgnoreCase("BURY_BLAST_EVAL"))	strBuryBlastEval = value;
		else if(key.equalsIgnoreCase("BURY_BLAST_IDENTITY"))	strBuryBlastEval = value;
		else if(key.equalsIgnoreCase("BURY_BLAST_PARAMS"))	strBuryBlastEval = value;
		else if(key.equalsIgnoreCase("CAP_ARGS"))	strCAPArgs = value;
		else if(key.equalsIgnoreCase("TC_BLAST_EVAL"))	strTCBlastEval = value;
		else if(key.equalsIgnoreCase("TC_BLAST_PARAMS"))	strTCBlastParams = value;
		else if(key.equalsIgnoreCase("User_EST_selfblast"))	strUserESTSelfBlast = value;
		else if(key.equalsIgnoreCase("JPAVE_unitrans_tselfblast")) strUnitransTSelfBlast = new String(value);
		else if(key.equalsIgnoreCase("JPAVE_unitrans_selfblast")) strUnitransSelfBlast = new String(value);
		else if(key.equalsIgnoreCase("JPAVE_pairs_limit")) {
			try {
				nPairsLimit = Integer.parseInt(value);
			}
			catch(Exception e) {
				nPairsLimit = -1;
			}
		}
		else if(key.equalsIgnoreCase("JPAVE_GO_DB")) strGODB = value;
		else if(key.matches("TC[0-9]+"))theTCs.add(value);
		else if(key.equalsIgnoreCase("JPAVE_tselfblast_args")) strUnitransTSelfBlastParams = value;
		else if(key.equalsIgnoreCase("JPAVE_selfblast_args"))	strUnitransSelfBlastParams = value;
		else if(key.equalsIgnoreCase("JPAVE_unitrans_type"))	nUnitransType = Integer.parseInt(value);
		else if(key.startsWith("JPAVE_DBtaxo_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(13));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setTaxo(value);
			annoData[index-1].setSelected(true);
		}
		else if(key.startsWith("#JPAVE_DBtaxo_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(14));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setTaxo(value);
			annoData[index-1].setSelected(false);
		}
		else if(key.startsWith("JPAVE_unitrans_DBblast_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(23));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setTabularFile(value);
			annoData[index-1].setSelected(true);
		}
		else if(key.startsWith("#JPAVE_unitrans_DBblast_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(24));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setTabularFile(value);
			annoData[index-1].setSelected(false);
		}
		else if(key.startsWith("JPAVE_DBsearch_pgm_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(19));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setSearchPgm(value);
			annoData[index-1].setSelected(true);
		}
		else if(key.startsWith("#JPAVE_DBsearch_pgm_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(20));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setSearchPgm(value);
			annoData[index-1].setSelected(false);
		}
		else if(key.startsWith("JPAVE_DBfasta_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(14));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setFastaDB(value);
			annoData[index-1].setSelected(true);
		}
		else if(key.startsWith("#JPAVE_DBfasta_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(15));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setFastaDB(value);
			annoData[index-1].setSelected(false);
		}
		else if(key.startsWith("JPAVE_DBargs_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(13));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setParams(value);
			annoData[index-1].setSelected(true);
		}
		else if(key.startsWith("#JPAVE_DBargs_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(14));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setParams(value);
			annoData[index-1].setSelected(false);
		}
		else if(key.startsWith("JPAVE_unitrans_subset_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(22));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setUnannotated(value.equalsIgnoreCase("yes"));
			annoData[index-1].setSelected(true);
		}
		else if(key.startsWith("#JPAVE_unitrans_subset_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(23));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setUnannotated(value.equalsIgnoreCase("yes"));
			annoData[index-1].setSelected(false);
		}
		else if(key.startsWith("JPAVE_DBdate_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(13));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setDate(value);
			annoData[index-1].setSelected(true);
		}
		else if(key.startsWith("#JPAVE_DBdate_")) { //AnnoDB
			int index = Integer.parseInt(key.substring(14));
			if(annoData[index-1] == null)
				annoData[index-1] = new AnnoData();
			annoData[index-1].setDate(value);
			annoData[index-1].setSelected(false);
		}
		else {
			String msg="Invalid sTCW.cfg keyword: " + key;
			System.err.println(msg);
			JOptionPane.showMessageDialog(null,  msg, "Error parsing sTCW.cfg", JOptionPane.PLAIN_MESSAGE);
			return false;
		}
		return true;
	}
	
	public AnnoData getAnnoDBAt(int pos) { return annoData.get(pos); }
	public void setAnnoDBAt(int pos, AnnoData data) { annoData.set(pos, data); }
	
	public ExpLibData getExpLibraryAt(int pos) { return expLibData.get(pos); }
	public int getExpLibraryPos(String libid, String prefix) {
		for(int x=0; x<expLibData.size(); x++) {
			if(expLibData.get(x) != null && expLibData.get(x).strLibID.equals(libid) &&  
					expLibData.get(x) != null && expLibData.get(x).strPrefix.equals(prefix))
				return x;
		}
		return -1;
	}
	public void setExpLibraryAt(int pos, ExpLibData data) { expLibData.set(pos, data); }
	public void removeExpLibraryAt(int pos) { expLibData.remove(pos); }
	
	public RepData getRepLibraryAt(int pos) { return repData.get(pos); }
	public void setRepLibraryAt(int pos, RepData data) { repData.set(pos, data); }
	
	public TransLibData getTransLibraryAt(int pos) { return transLibData.get(pos); }
	public void setTransLibraryAt(int pos, TransLibData data) { transLibData.set(pos, data); }
	
	public void setAssemblyID(String id) { strAssemblyID = id; }
	public String getAssemblyID() { return strAssemblyID; }
	
	public void setPAVEDB(String db) { strPAVEdb = db; }
	public String getPAVEDB() { return strPAVEdb; }

	public void setNumCPUs(int CPUs) { nCPUs = CPUs; }
	public int getNumCPUs() { return nCPUs; }
	
	public void setClique(String clique) { strClique = clique; }
	public String getClique() { return strClique; }
	
	public void setCliqueBlastEval(String eval) { strCliqueBlastEval = eval; }
	public String getCliqueBlastEval() { return strCliqueBlastEval; }
	
	public boolean isProteinDB() { return bProteinDB; }
	public void setProteinDB(boolean isProteinDB) { bProteinDB = isProteinDB; }
	
	public void setCliqueBlastParam(String param) { strCliqueBlastParam = param; }
	public String getCliqueBlastParam() { return strCliqueBlastParam; }
	
	public void setSelfJoin(String selfJoin) { strSelfJoin = selfJoin; }
	public String getSelfJoin() { return strSelfJoin; }
	
	public void setUnitransType(int type) { nUnitransType = type; }
	public int getUnitransType() { return nUnitransType; }
	
	public void setUnitransTSelfBlast(String filename) { strUnitransTSelfBlast = filename; }
	public String getUnitransTSelfBlast() { return strUnitransTSelfBlast; }
	
	public void setDefaultAnnoDBBlastParams(String params) { strDefaultAnnoBlastParams = params; }
	public String getDefaultAnnoDBBlastParams() { return strDefaultAnnoBlastParams; }
	
	public void setUnitransSelfBlast(String filename) { strUnitransSelfBlast = filename; }
	public String getUnitransSelfBlast() { return strUnitransSelfBlast; }

	public void setUnitransTSelfBlastParams(String parameters) { strUnitransTSelfBlastParams = parameters; }
	public String getUnitransTSelfBlastParams() { return strUnitransTSelfBlastParams; }
	
	public void setUnitransSelfBlastParams(String parameters) { strUnitransSelfBlastParams = parameters; }
	public String getUnitransSelfBlastParams() { return strUnitransSelfBlastParams; }
	
	public void setPairsLimit(int limit) { nPairsLimit = limit; }
	public int getPairsLimit() { return nPairsLimit; }
	
	public void setGODB(String dbName) { strGODB = dbName;  }
	public String getGODB() { return strGODB; }

	public void setSkipAssembly(boolean skip) { bSkipAssembly = skip; }
	public boolean getSkipAssembly() { return bSkipAssembly; }
	
	public void setUseTransNames(boolean useNames) { bUseTransNames = useNames; }
	public boolean getUseTransNames() { return bUseTransNames; }
	
	public void setProjectName(String name) { strProject = name; }
	public String getProjectName() { return strProject; }
	
	public void setBuryBlastEval(String eval) { strBuryBlastEval = eval; }
	public String getBuryBlastEval() { return strBuryBlastEval; }
	
	public void setBuryBlastIdentity(String identity) { strBuryBlastIdentity = identity; }
	public String getBuryBlastIdentity() { return strBuryBlastIdentity; }
	
	public void setBuryBlastParams(String params) { strBuryBlastParams = params; }
	public String getBuryBlastParams() { return strBuryBlastParams; }
	
	public void setCAPArgs(String args) { strCAPArgs = args; }
	public String getCAPArgs() { return strCAPArgs; }
	
	public void setTCBlastEval(String eval) { strTCBlastEval = eval; }
	public String getTCBlastEval() { return strTCBlastEval; }
	
	public void setTCBlastParams(String params) { strTCBlastParams = params; }
	public String getTCBlastParams() { return strTCBlastParams; }
	
	public void setUserESTSelfBlast(String file) { strUserESTSelfBlast = file; }
	public String getUserESTSelfBlast() { return strUserESTSelfBlast; }
	
	public int getNumTCs() { return theTCs.size(); }
	public void addTC(String tc) { theTCs.add(tc); }
	public String getTCAt(int pos) { return theTCs.get(pos); }
	public void clearTCs() { theTCs.clear(); }
	
	public boolean isLibraryLoaded() { return bLibLoaded; }
	public void setLibraryLoaded(boolean loaded) { bLibLoaded = loaded; }
	
	public int getNumCountFiles() { return countData.size(); }
	public void addNewCountFile(String file, String header) { 
		countData.add(new CountData());
		countData.get(countData.size() - 1).setFile(file);
		countData.get(countData.size() - 1).setHeader(header);
	}
	public void setCountFileAt(int pos, String file) { countData.get(pos).strFile = file; }
	public void setCountLabelAt(int pos, String label) { countData.get(pos).strHeader = label; }
	
	public String getCountFileAt(int pos) { return countData.get(pos).strFile; }
	public String getCountHeaderAt(int pos) { return countData.get(pos).strHeader; }
	public void clearCountFiles() { countData.clear(); }

	public void clearAnnoDBload() { // CAS 5/10/15 for ManagerFrame remove annotation
		for (AnnoData ad : annoData) ad.setLoaded(false);
	}
	// The manager data for a project consists of the following arrays of data
	private Vector<TransLibData> transLibData = null;
	private Vector<ExpLibData> expLibData = null;
	private Vector<RepData> repData = null;
	private Vector<CountData> countData = null;
	private Vector<AnnoData> annoData = null;
	
	//Common Settings
	private String strProject = "";
	private String strAssemblyID = "";
	private String strPAVEdb = "";

	private int nCPUs = 1;
	private boolean bSkipAssembly = true;
	private boolean bUseTransNames = false;
	private String strClique = "";
	private String strCliqueBlastEval = "";
	private String strCliqueBlastParam = "";
	private String strSelfJoin = "";
	
	private String strBuryBlastEval = "";
	private String strBuryBlastIdentity = "";
	private String strBuryBlastParams = "";
	private String strCAPArgs = "";
	private String strTCBlastEval = "";
	private String strTCBlastParams = "";
	private String strUserESTSelfBlast = "";
	private Vector<String> theTCs = null;
	
	private String strDefaultAnnoBlastParams = "";
	private String strUnitransTSelfBlast = null;
	private String strUnitransSelfBlast = null;
	private String strUnitransTSelfBlastParams = "";
	private String strUnitransSelfBlastParams = "";
	
	//Load status flags
	private boolean bLibLoaded = false;
	
	//AnnoDB data
	private int nUnitransType = -1;
	private int nPairsLimit = -1;
	private String strGODB = "";
	
	//Set after database is loaded
	private boolean bProteinDB = false;

	/*******************************************
	 * Files associated with replica data 
	 */
	public class CountData {
		public void setFile(String file) { strFile = file; }
		public String getFile() { return strFile; }		
		public void setHeader(String header) { strHeader = header; }
		public String getHeader() { return strHeader; }
		
		private String strFile = "";
		private String strHeader = "";
	}
	/*********************************************
	 * Data for replica libraries
	 */
	public class RepData extends Attributes {
		public void setRepID(String libName) { strRepID = libName; }
		public String getRepID() { return strRepID; }		
		public String getLibID() { return strLibID; }
		public void setLibID(String name) { strLibID = name; }		
		public void setTransID(String transLib) { strTransID = transLib; }
		public String getTransID() { return strTransID; }
		public void setExpPrefix(String prefix) { strPrefix = prefix; }
		public String getExpPrefix() { return strPrefix; }
		
		private String strRepID = "";
		private String strLibID = "";
		private String strTransID = "";
		private String strPrefix = "";
	}
	
	// for updating the database
    public String getTransLib(int index) {
    			TransLibData t = transLibData.get(index);
			String theStatement = "UPDATE library SET ";
			theStatement += "title = '" + t.getTitle() + "', ";
			theStatement += "organism = '" + t.getOrganism() + "', ";
			theStatement += "cultivar = '" + t.getCultivar() + "', ";
			theStatement += "strain = '" + t.getStrain() + "', ";
			theStatement += "tissue = '" + t.getTissue() + "', ";
			theStatement += "stage = '" + t.getStage() + "', ";
			theStatement += "treatment = '" + t.getTreatment() + "', ";
			theStatement += "year = '" + t.getYear() + "', ";
			theStatement += "source = '" + t.getSource() + "' ";
			theStatement += "WHERE libid = '" + t.getTransLibID() + "'";
			return theStatement;
    }
	/*******************************************************
	 * Data for Transcript or Read libraries
	 * 	note: Read libraries have libid like expressions libraries, but are grouped with TransLibs.
	 */
	public class TransLibData extends Attributes {
		public void setTransLibID(String id) { strTransLibID = id; }
		public String getTransLibID() { return strTransLibID; }		
		public void setSeqFile(String filename) { strSeqFile = filename; }
		public String getSeqFile() { return strSeqFile; }	
		public void setQualFile(String filename) { strQualFile = filename; }
		public String getQualFile() { return strQualFile; }		
		public void setExpFile(String filename) { strExpFile = filename; }
		public String getExpFile() { return strExpFile; }
		public void setExpPrefix(String prefix) { strExpPrefix = prefix; }
		public String getExpPrefix() { return strExpPrefix; }
		public void setFivePrimeSuffix(String suffix) { strFivePrimeSuf = suffix; }
		public String getFivePrimeSuffix() { return strFivePrimeSuf; }
		public void setThreePrimeSuffix(String suffix) { strThreePrimeSuf = suffix; }
		public String getThreePrimeSuffix() { return strThreePrimeSuf; }

		private String strTransLibID = "";
		private String strSeqFile = "";
		private String strQualFile = "";
		private String strExpFile = "";
		private String strExpPrefix = "";
		private String strFivePrimeSuf = "";
		private String strThreePrimeSuf = "";
	}
	/***************************************************
	 * Data for Expression level libraries
	 */
	public class ExpLibData extends Attributes {
		public ExpLibData() {}
		
		// transfers information from TransLibData to new ExpLibData
		public ExpLibData(String transID, TransLibData libData) {
			strLibID = libData.strTransLibID;
			strTransID = transID;
			strPrefix = libData.strExpPrefix;
			nNumReps = 1;
			
			setTitle(libData.getTitle());
			setCultivar(libData.getCultivar());
			setTissue(libData.getTissue());
			setStage(libData.getStage());
			setTreatment(libData.getTreatment());
			setOrganism(libData.getOrganism());
			setStrain(libData.getStrain());
			setYear(libData.getYear());
			setSource(libData.getSource());
		}
		public void setLibID(String id) { strLibID = id; }
		public String getLibID() { return strLibID; }		
		public void setTransID(String id) { strTransID = id; }
		public String getTransID() { return strTransID; }
		public void setPrefix(String prefix) { strPrefix = prefix; }
		public String getPrefix() { return strPrefix; }		
		public void setNumReps(int reps) { nNumReps = reps; }
		public int getNumReps() { return nNumReps; }
		public void addNumReps() {nNumReps++;}
		
		private String strLibID = "";
		private String strTransID = "";
		private String strPrefix = "";
		private int nNumReps = 1;

		public boolean equals(Object exp) {
			if(exp instanceof ExpLibData)
				return strLibID.equals(((ExpLibData)exp).strLibID) && strTransID.equals(((ExpLibData)exp).strTransID) 
						 && strPrefix.equals(((ExpLibData)exp).strPrefix);
			return false;
		}
	}
	/**************************************************************
	 * Attributes for either Transcript/Read or Expression Level Libraries
	 */
	public class Attributes {
		public boolean setAttribute(String key, String value) {
			if(key.equalsIgnoreCase("title")) strTitle = value;
			else if(key.equalsIgnoreCase("cultivar")) strCultivar = value;
			else if(key.equalsIgnoreCase("tissue"))	strTissue = value;
			else if(key.equalsIgnoreCase("stage"))	strStage = value;
			else if(key.equalsIgnoreCase("treatment"))	strTreatment = value;
			else if(key.equalsIgnoreCase("organism"))	strOrganism = value;
			else if(key.equalsIgnoreCase("strain"))	strStrain = value;
			else if(key.equalsIgnoreCase("year"))	strYear = value;
			else if(key.equalsIgnoreCase("source"))	strSource = value;
			else	return false;
			return true;
		}

		public void setTitle(String title) { strTitle = title; }
		public String getTitle() { return strTitle; }	
		public void setCultivar(String cultiVar) { strCultivar = cultiVar; }
		public String getCultivar() { return strCultivar; }		
		public void setTissue(String tissue) { strTissue = tissue; }
		public String getTissue() { return strTissue; }		
		public void setStage(String stage) { strStage = stage; }
		public String getStage() { return strStage; }		
		public void setTreatment(String treatment) { strTreatment = treatment; }
		public String getTreatment() { return strTreatment; }		
		public void setOrganism(String organism) { strOrganism = organism; }
		public String getOrganism() { return strOrganism; }		
		public void setStrain(String strain) { strStrain = strain; }
		public String getStrain() { return strStrain; }		
		public void setYear(String year) { strYear = year; }
		public String getYear() { return strYear; }		
		public void setSource(String source) { strSource = source; }
		public String getSource() { return strSource; }
		
		private String strTitle = "";
		private String strCultivar = "";
		private String strTissue = "";
		private String strStage = "";
		private String strTreatment = "";
		private String strOrganism = "";
		private String strStrain = "";
		private String strYear = "";
		private String strSource = "";
	}
	/**************************************************
	 * Data for annoDB
	 */
	public class AnnoData {
		public void setLoaded(boolean loaded) { bLoaded = loaded; }
		public boolean isLoaded() { return bLoaded; }		
		public void setSelected(boolean selected) { bSelected = selected; }
		public boolean isSelected() { return bSelected; }	
		
		public void setTaxo(String taxo) { strTaxo = taxo; }
		public String getTaxo() { return strTaxo; }		
		public void setTabularFile(String filename) { strTabularFile = filename; }
		public String getTabularFile() { return strTabularFile; }		
		public void setFastaDB(String filename) { strFastaDB = filename; }
		public String getFastaDB() { return strFastaDB; }		
		public void setParams(String args) { strParams = args; }
		public String getParams() { return strParams; }		
		public void setUnannotated(boolean subset) { bUnannotated = subset; }
		public boolean getUnannotated() { return bUnannotated; }		
		public void setDate(String date) { strDate = date; }
		public String getDate() { return strDate; }
		public void setSearchPgm(String p) { searchPgm = p; }
		public String getSearchPgm() {return searchPgm; }
		
		public boolean equals(Object obj) {
			if(obj instanceof AnnoData) {
				AnnoData ad = (AnnoData)obj;
				if(ad.strTaxo.equals(strTaxo))
					return ad.strFastaDB.equals(strFastaDB);
				return ad.strTaxo.equals(strTaxo);
			}
			return false;
		}
		
		private boolean bLoaded = false;
		private boolean bSelected = true;
		private String strTaxo = "";
		private String strTabularFile = "";
		private String strFastaDB = "";
		private String strParams = "";
		private boolean bUnannotated = false;
		private String strDate = "";
		private String searchPgm=EditAnnoPanel.SEARCH_PGM_DEFAULT;
	}
	
	public static void showData(String msg, ManagerData data) { // for debugging
		System.out.println(">>" + msg);
			System.out.println("Trans Libs");
			for(int x=0; x<data.getNumTransLibs(); x++) {
				System.out.print("\n\tTransId: " + data.getTransLibraryAt(x).strTransLibID);
				if (data.getTransLibraryAt(x).strExpFile.length() > 0)
					System.out.print("\t   ExpFile: " + data.getTransLibraryAt(x).strExpFile);
			}
			
			System.out.println("\nExp Libs");
			for(int x=0; x<data.getNumExpLibs(); x++) {
				System.out.print("\n\tLibId: " + data.getExpLibraryAt(x).strLibID);
				System.out.print("\tTransId: " + data.getExpLibraryAt(x).strTransID);
				System.out.print("\tReps: " + data.getExpLibraryAt(x).nNumReps);
			}
						
			System.out.println("\nReps");
			for(int x=0; x<data.getNumReps(); x++) {
				System.out.print("\n\tRepId: " + data.getRepLibraryAt(x).strRepID);
				System.out.print("\t   RepId: " + data.getRepLibraryAt(x).strLibID);
				System.out.print("\t   TransId: " + data.getRepLibraryAt(x).strTransID);

			}
		System.out.println("\ndone");
	}
}
